package se.liu.oschi129.game.objects.blocks.solid;

import se.liu.oschi129.world.model.World;
import se.liu.oschi129.world.model.WorldGraphics;
import se.liu.oschi129.world.objects.WorldObject;
import se.liu.oschi129.world.objects.WorldStaticObject;
import se.liu.oschi129.animation.*;

import java.util.ArrayList;
import java.util.List;

/**
 * This is an abstract class for regular blocks. It can contain items but it cannot be broken.
 * 
 * @author oschi129
 */
public abstract class ObjectBlock extends WorldStaticObject {
	
	// This variable contains information of which phase the object is in (0 - 2 = moving up, 3 - 5 moving down)
	private int step;
	
	// The translation among the y-axis
	private double dy;
	
	// Whatever the block is hit or not
	private boolean hit;
	
	// The animation used when the block is empty
	private Animation emptyAnimation;
	
	// A list of the content in ObjectBlock
	private final List<WorldObject> content = new ArrayList<WorldObject>();
	
	/**
	 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	 * - - - - - - - - - - - - Constructors - - - - - - - - - - - 
	 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	 */
	
	public ObjectBlock(double x, double y, double width, double height) {
		super(x, y, width, height);
		setType(Type.SOLID);
		hit = false;
		step = 0;
		dy = 0;
	}
	
	public ObjectBlock(Animation animation, boolean visible, double x, double y, double width, double height) {
		this(x, y, width, height);
		setAnimation(animation);
		setEmptyAnimation(animation);
		setVisible(visible);
	}
	
	/**
	 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	 * - - - - - - - - - - - Public methods - - - - - - - - - - - 
	 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	 */
	
	/** Adds a content to the block */
	public void addContent(WorldObject content) {
		this.content.add(content);
	}
	
	/** Removes a content from the block */
	public void removeContent(WorldObject content) {
		this.content.remove(content);
	}
	
	/** Removes the last added content from the block */
	public WorldObject removeLastContent() {
		if (content.isEmpty()) 
			return null;
		else
			return content.remove(0);
	}
	
	/** Returns true if the block has no content */
	public boolean isEmpty() {
		return content.isEmpty();
	}
	
	/** Sets the animation used when the block is empty */
	public void setEmptyAnimation(Animation emptyAnimation) {
		this.emptyAnimation = emptyAnimation;
	}
	
	/** Returns the animation used when the block is empty */
	public Animation getEmptyAnimation() {
		return emptyAnimation;
	}
	
	/** Hits the block to remove one item of its content adding it to the world */
	@Override public void performHitAction(World world) {
		if (hit)
			return;
		WorldObject obj = removeLastContent();
		if (obj != null) {
			world.addObjectSynchronized(obj,getX(),getY()-2); // Add one item from the block to the world
			hit = true;
			setVisible(true);
			world.setPoints(world.getPoints() + 10);
			if (isEmpty())
				setAnimation(getEmptyAnimation()); // Change animation when the block is empty
		} 
	}
	
	@Override public void performStepAction(World world) {
		super.performStepAction(world);
		if (hit) {
			if (step == 4) {
				dy = 0; // Translation is completed
				step = 0;
				hit = false;
			} else if (step < 2)
				dy-=4; // Moving up
			else 
				dy+=4; // Moving down
			step++;
		}
	}
	
	/** Overrides the drawing action - the image needs to be translated when hit */
	@Override public void performDrawingAction(WorldGraphics worldg) {
		worldg.drawAnimation(getX(), getY() + dy, getWidth(), getHeight(), getAnimation(), (int) getImageIndex());
	}
	

}
